// -------------------------------------------------------------
//      GEANT4 project of test
//
//      Modified: 2025.11.06
//
// -------------------------------------------------------------

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....

#include <G4VUserPhysicsList.hh>

#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "G4RunManagerFactory.hh"
#include "G4ScoringManager.hh"
#include "G4Types.hh"
#include "G4UIExecutive.hh"
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
#include "PhysicsList.hh"
#include "Randomize.hh"

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....

int main(int argc, char** argv)
{
    ///=================================== detect interactive mode (if no arguments) and define UI session
    G4UIExecutive* ui = nullptr;
    if (argc == 1) ui = new G4UIExecutive(argc, argv);

    ////=================================== Set the Random engine
    const auto seed = (G4int)time(NULL);
    G4Random::setTheSeed(seed);
    G4cout << G4endl << " Initial seed = " << seed << G4endl << G4endl;

    ///=================================== Construct the default run manager
    auto* runManager = G4RunManagerFactory::CreateRunManager();
    G4int nThreads = std::min(G4Threading::G4GetNumberOfCores(), 4);
    runManager->SetNumberOfThreads(nThreads);
    G4cout << "===== Geant4 is started with " << runManager->GetNumberOfThreads() << " threads =====" << G4endl;

    ///=================================== Scoring manager
    auto* const scManager = G4ScoringManager::GetScoringManager();
    scManager->SetVerboseLevel(1);

    ///=================================== Detector construction
    DetectorConstruction* det = new DetectorConstruction();
    runManager->SetUserInitialization(det);

    ///=================================== Physics lists
    auto* const phyList = (G4VUserPhysicsList*)new PhysicsList();
    runManager->SetUserInitialization(phyList);

    //set user action classes
    runManager->SetUserInitialization(new ActionInitialization(det));

    //initialize visualization
    G4VisManager* visManager = nullptr;

    //get the pointer to the User Interface manager
    G4UImanager* UImanager = G4UImanager::GetUIpointer();

    if (ui)
    {
        ///interactive mode
        visManager = new G4VisExecutive;
        visManager->Initialize();
        UImanager->ApplyCommand("/control/execute init_vis.mac");
        ui->SessionStart();
        delete ui;
    }
    else
    {
        ///batch mode
        G4String command = "/control/execute ";
        G4String fileName = argv[1];
        UImanager->ApplyCommand(command + fileName);
    }

    //job termination
    delete visManager;
    delete runManager;
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
